open NodeJs

module T = {
  type read = {
    id: string,
    pid: string,
    deep: string,
    name: string,
    pinyin_prefix: string,
    pinyin: string,
    ext_id: string,
    ext_name: string,
  }
}

include CSV.Make(T)

type rec item = {
  id: string,
  pid: string,
  name: string,
  pinyin_prefix: string,
  children: array<item>,
}

type rec results = {
  id: string,
  name: string,
  header: string,
  children: array<results>,
}

let origin = []

let fill = (a: array<T.read>) => {
  a->Array.map(item => {
    {
      id: item.id,
      pid: item.pid,
      pinyin_prefix: item.pinyin_prefix,
      name: item.ext_name,
      children: [],
    }
  })
}

let buildTree = (nodes: array<item>) => {
  let m = Map.make()
  nodes->Array.forEach(v => {
    m->Map.set(v.id, v)
  })
  let results = []
  nodes->Array.forEach(v => {
    if v.pid == "0" {
      results->Array.push(v)
    } else {
      switch m->Map.get(v.pid) {
      | Some(node) => node.children->Array.push(v)
      | _ => ()
      }
    }
  })
  results
}

let rec slim = (a: array<item>) => {
  a->Array.map(v => {
    id: v.id,
    name: v.name,
    header: v.pinyin_prefix->String.toUpperCase,
    children: slim(v.children),
  })
}

Fs.createReadStream("./area.csv")
->Stream.pipe(
  make(
    ~opts={headers: ["id", "pid", "deep", "name", "pinyin_prefix", "pinyin", "ext_id", "ext_name"]},
  ),
)
->Stream.onData(row => origin->Array.push(row))
->Stream.onEnd(() => {
  let filled = fill(origin->Array.sliceToEnd(~start=1))
  let tree = buildTree(filled)->slim
  JSON.stringifyAny(tree)
  ->Option.map(v => Fs.writeFileSync("area.json", Buffer.fromString(v)))
  ->ignore
})
->ignore
